/*
** malloc.c for malloc in /home/morel_t//Rendu/systemUnix
**
** Made by thomas morel
** Login   <morel_t@epitech.net>
**
** Started on  Mon Jan 30 09:51:05 2012 thomas morel
** Last update Fri Feb  3 12:12:20 2012 florian jousseau
*/

#include <pthread.h>
/* #include <sys/types.h> */
#include "alloc.h"

void			*g_first_block = NULL;
pthread_mutex_t		g_mutex = PTHREAD_MUTEX_INITIALIZER;

static t_alloc	first_time(size_t size)
{
  t_alloc	first;

  first = extend_heap(NULL, size);
  if (!first)
    return (NULL);
  g_first_block = first;
  return (first);
}

static t_alloc	other_time(t_alloc last, size_t size)
{
  t_alloc	other;

  other = find_block(&last, size);
  if (other)
    {
      if ((other->size - size) >= (BLOCK_SIZE))
	split_block(other, size);
      other->free = 0;
    }
  else
    {
      other = extend_heap(last, size);
      if (!other)
	return (NULL);
    }
  return (other);
}

void		*malloc(size_t size)
{
  t_alloc	block;
  t_alloc	last;

  /* printf("MALLOC START\n"); */
  pthread_mutex_lock(&g_mutex);
  if (size == 0)
    {
      pthread_mutex_unlock(&g_mutex);
      /* printf("MALLOC END\n"); */
      return (NULL);
    }
  size = align4(size);
  if (g_first_block == NULL)
      block = first_time(size);
  else
    {
      last = g_first_block;
      block = other_time(last, size);
    }
  pthread_mutex_unlock(&g_mutex);
  /* printf("MALLOC END\n"); */
  if (block)
    return (block->delim);
  return (NULL);
}

